import 'package:flutter/material.dart';

class CurvedRectArcTween extends MaterialRectArcTween {
  CurvedRectArcTween({
    Rect? begin,
    Rect? end,
  }) : super(begin: begin, end: end);
  @override
  Rect lerp(double t) {
    double height = end?.top ?? 0 - (begin?.top ?? 0);
    double width = end?.left ?? 0 - (begin?.left ?? 0);
    double animatedX = begin?.left ?? 0 + (t * width);
    double animatedY = begin?.top ?? 0 + (t * height);

    return Rect.fromLTWH(animatedX, animatedY, 1, 1);
  }
}

class HeroPageRoute extends PageRouteBuilder {
  final String tag;
  final Widget child;
  HeroPageRoute({
    required this.tag,
    required this.child,
  }) : super(
            opaque: false,
            transitionDuration: const Duration(milliseconds: 400),
            reverseTransitionDuration: const Duration(milliseconds: 400),
            pageBuilder: (ctx, a1, a2) {
              return PageRouteTransition(
                animation: a1,
                child: child,
              );
            });
}

class PageRouteTransition extends AnimatedWidget {
  const PageRouteTransition({
    Key? key,
    required this.child,
    required this.animation,
  }) : super(key: key, listenable: animation);
  final Widget child;
  final Animation<double> animation;
  static final opacityTween = Tween<double>(begin: 0.0, end: 1.0);
  static final elevationTween = Tween<double>(begin: 6.0, end: 0.0);
  static final borderRadiusTween = BorderRadiusTween(
    begin: BorderRadius.circular(0.0),
    end: BorderRadius.zero,
  );
  @override
  Widget build(BuildContext context) {
    final animation = listenable as Animation<double>;
    return Material(
      type: MaterialType.transparency,
      clipBehavior: Clip.antiAlias,
      elevation: elevationTween.evaluate(animation),
      borderRadius: borderRadiusTween.evaluate(animation),
      child: Stack(
        children: [
          Opacity(
            opacity: opacityTween.evaluate(animation),
            child: child,
          ),
        ],
      ),
    );
  }
}
